package com.twobu.twobuinsight.service.impl;

import cn.hutool.json.JSONUtil;
import com.twobu.twobuinsight.config.ExternalApiConfig;
import com.twobu.twobuinsight.dto.*;
import com.twobu.twobuinsight.exception.BusinessException;
import com.twobu.twobuinsight.security.UserContextHolder;
import com.twobu.twobuinsight.service.AIResearchService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.List;

/**
 * AI研究服务实现类
 */
@Slf4j
@Service
public class AIResearchServiceImpl implements AIResearchService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private ExternalApiConfig apiConfig;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 提交研究任务
     * @param request 任务提交请求
     * @return 任务提交响应
     */
    @Override
    public TaskSubmitResponse submitTask(TaskSubmitRequest request) {
        log.info("提交研究任务: {}", request);

        try {
            // 构建请求头
            HttpHeaders headers = buildHeaders();

            // 构建请求实体
            HttpEntity<TaskSubmitRequest> requestEntity = new HttpEntity<>(request, headers);

            // 构建完整URL
            String url = apiConfig.getBaseUrl() + apiConfig.getTaskSubmitPath();
            log.info("调用外部API: {}", url);

            // 发送请求
            ResponseEntity<ExternalApiResponse<TaskSubmitResponse>> responseEntity = restTemplate.exchange(
                    url,
                    HttpMethod.POST,
                    requestEntity,
                    new ParameterizedTypeReference<ExternalApiResponse<TaskSubmitResponse>>() {}
            );

            // 处理响应
            ExternalApiResponse<TaskSubmitResponse> apiResponse = responseEntity.getBody();
            log.info("外部API响应: {}", apiResponse);

            //存储到缓存
            TaskSubmitResponse data = apiResponse.getData();
            TaskHistorySimpleDTO taskHistorySimpleDTO = new TaskHistorySimpleDTO();
            taskHistorySimpleDTO.setTaskId(data.getTaskId());
            taskHistorySimpleDTO.setUserInstruction(request.getUserInstruction());
            taskHistorySimpleDTO.setCreateTime(LocalDateTime.now());
            taskHistorySimpleDTO.setFinishFlag(false);
            String key = "user:taskId:mapper:" + UserContextHolder.getCurrentUserId();
            stringRedisTemplate.opsForSet().add(key,JSONUtil.toJsonStr(taskHistorySimpleDTO));

            if (apiResponse == null) {
                throw new BusinessException("外部API响应为空");
            }

            if (!apiResponse.isSuccess()) {
                throw new BusinessException("外部API调用失败: " + apiResponse.getMessage());
            }

            return apiResponse.getData();
        } catch (RestClientException e) {
            log.error("调用外部API异常", e);
            throw new BusinessException("调用外部API异常: " + e.getMessage());
        } catch (Exception e) {
            log.error("提交研究任务异常", e);
            throw new BusinessException("提交研究任务异常: " + e.getMessage());
        }
    }

    /**
     * 获取任务结果
     * @param taskId 任务ID
     * @return 任务结果响应
     */
    @Override
    public TaskOutcomeResponse getTaskOutcome(String taskId) {
        log.info("获取任务结果: {}", taskId);

        try {
            // 构建请求头
            HttpHeaders headers = buildHeaders();

            // 构建请求实体
            HttpEntity<?> requestEntity = new HttpEntity<>(headers);

            // 构建完整URL
            String url = apiConfig.getBaseUrl() + apiConfig.getTaskOutcomePath() + "?task_id=" + taskId;
            log.info("调用外部API: {}", url);

            // 发送请求
            ResponseEntity<ExternalApiResponse<TaskOutcomeResponse>> responseEntity = restTemplate.exchange(
                    url,
                    HttpMethod.GET,
                    requestEntity,
                    new ParameterizedTypeReference<ExternalApiResponse<TaskOutcomeResponse>>() {}
            );

            // 处理响应
            ExternalApiResponse<TaskOutcomeResponse> apiResponse = responseEntity.getBody();
            log.info("外部API响应: {}", apiResponse);

            if (apiResponse == null) {
                throw new BusinessException("外部API响应为空");
            }

            if (!apiResponse.isSuccess()) {
                throw new BusinessException("外部API调用失败: " + apiResponse.getMessage());
            }

            return apiResponse.getData();
        } catch (RestClientException e) {
            log.error("调用外部API异常", e);
            throw new BusinessException("调用外部API异常: " + e.getMessage());
        } catch (Exception e) {
            log.error("获取任务结果异常", e);
            throw new BusinessException("获取任务结果异常: " + e.getMessage());
        }
    }

    /**
     * 接收任务结果更新
     * @param taskOutcome 任务结果
     */
    @Override
    public void acceptTaskOutcome(TaskOutcomeResponse taskOutcome) {
        log.info("接收任务结果更新: {}", taskOutcome);

        // 这里可以实现任务结果更新的处理逻辑
        // 例如：保存到数据库、发送通知等

        // 暂时只记录日志
        log.info("任务结果: taskId={}, status={}, response={}",
                taskOutcome.getTaskId(), taskOutcome.getStatus(),
                taskOutcome.getOutcome() != null ? taskOutcome.getOutcome().getResponse() : null);
    }


    /**
     * 获取任务状态
     * @param taskId 任务ID
     * @return 任务状态响应
     */
    @Override
    public TaskStatusListResponse getTaskStatus(String taskId) {
        log.info("获取任务状态: {}", taskId);

        try {
            // 构建请求头
            HttpHeaders headers = buildHeaders();

            // 构建请求实体
            HttpEntity<?> requestEntity = new HttpEntity<>(headers);

            // 构建完整URL
            String url = apiConfig.getBaseUrl() + apiConfig.getTaskStatusPath() + "?taskId=" + taskId;
            log.info("调用外部API: {}", url);

            // 发送请求 - 使用TaskStatusListResponse作为响应类型
            ResponseEntity<ExternalApiResponse<List<TaskStatusItem>>> responseEntity = restTemplate.exchange(
                    url,
                    HttpMethod.GET,
                    requestEntity,
                    new ParameterizedTypeReference<ExternalApiResponse<List<TaskStatusItem>>>() {}
            );

            // 处理响应
            ExternalApiResponse<List<TaskStatusItem>> apiResponse = responseEntity.getBody();
            log.info("外部API响应: {}", apiResponse);

            if (apiResponse == null) {
                throw new BusinessException("外部API响应为空");
            }

            if (!apiResponse.isSuccess()) {
                throw new BusinessException("外部API调用失败: " + apiResponse.getMessage());
            }

            // 将ExternalApiResponse转换为TaskStatusListResponse
            return convertToTaskStatusListResponse(apiResponse);
        } catch (RestClientException e) {
            log.error("调用外部API异常", e);
            throw new BusinessException("调用外部API异常: " + e.getMessage());
        } catch (Exception e) {
            log.error("获取任务状态异常", e);
            throw new BusinessException("获取任务状态异常: " + e.getMessage());
        }
    }

    /**
     * 将ExternalApiResponse转换为TaskStatusListResponse
     * @param apiResponse 外部API响应
     * @return 任务状态列表响应
     */
    private TaskStatusListResponse convertToTaskStatusListResponse(ExternalApiResponse<List<TaskStatusItem>> apiResponse) {
        if (apiResponse == null || apiResponse.getData() == null) {
            return new TaskStatusListResponse();
        }

        TaskStatusListResponse response = new TaskStatusListResponse();
        response.setData(apiResponse.getData());
        return response;
    }

    /**
     * 将任务状态列表转换为任务结果响应
     * @param statusItems 任务状态项列表
     * @param taskId 任务ID
     * @return 任务结果响应
     */
    private TaskOutcomeResponse convertToTaskOutcomeResponse(List<TaskStatusItem> statusItems, String taskId) {
        if (statusItems == null || statusItems.isEmpty()) {
            return createEmptyTaskOutcomeResponse(taskId);
        }

        // 获取最后一个状态项
        TaskStatusItem latestStatus = statusItems.get(statusItems.size() - 1);

        // 创建任务结果响应
        TaskOutcomeResponse response = new TaskOutcomeResponse();
        response.setTaskId(taskId);
        response.setStatus(mapOverallStatus(latestStatus.getOverallStatus()));

        // 如果任务已完成，设置结果内容
        if ("completed".equalsIgnoreCase(latestStatus.getOverallStatus())) {
            TaskOutcomeResponse.TaskOutcome outcome = new TaskOutcomeResponse.TaskOutcome();
            outcome.setResponse(latestStatus.getMessage()); // 使用消息作为响应内容

            // 设置元数据（如果需要）
            TaskOutcomeResponse.TaskMetadata metadata = new TaskOutcomeResponse.TaskMetadata();
            // 从第一个状态项中获取股票代码和日期范围（如果有）
            if (!statusItems.isEmpty() && statusItems.get(0).getPayload() != null) {
                TaskStatusItem firstItem = statusItems.get(0);
                if (firstItem.getPayload().containsKey("stock_code")) {
                    metadata.setStockCode(firstItem.getPayload().get("stock_code").toString());
                }
                if (firstItem.getPayload().containsKey("from_date")) {
                    metadata.setFromDate(firstItem.getPayload().get("from_date").toString());
                }
                if (firstItem.getPayload().containsKey("to_date")) {
                    metadata.setToDate(firstItem.getPayload().get("to_date").toString());
                }
            }

            outcome.setMetadata(metadata);
            response.setOutcome(outcome);
        }

        return response;
    }

    /**
     * 创建空的任务结果响应
     * @param taskId 任务ID
     * @return 任务结果响应
     */
    private TaskOutcomeResponse createEmptyTaskOutcomeResponse(String taskId) {
        TaskOutcomeResponse response = new TaskOutcomeResponse();
        response.setTaskId(taskId);
        response.setStatus("unknown");
        return response;
    }

    /**
     * 映射整体状态
     * @param overallStatus 原始整体状态
     * @return 映射后的状态
     */
    private String mapOverallStatus(String overallStatus) {
        if (overallStatus == null) {
            return "unknown";
        }

        switch (overallStatus.toLowerCase()) {
            case "processing":
                return "in_progress";
            case "completed":
                return "completed";
            case "failed":
                return "failed";
            case "pending":
                return "pending";
            default:
                return "unknown";
        }
    }

    /**
     * 构建请求头
     * @return HttpHeaders
     */
    private HttpHeaders buildHeaders() {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Content-Type", "application/json");
        headers.set("Accept", "application/json");

        // 如果有API密钥，添加到请求头
        if (apiConfig.getApiKey() != null && !apiConfig.getApiKey().isEmpty()) {
            headers.set("X-API-Key", apiConfig.getApiKey());
        }

        return headers;
    }

    /**
     * 生成任务PDF报告
     * @param taskId 任务ID
     * @return PDF生成响应
     */
    @Override
    public TaskPDFResponse generateTaskPDF(String taskId) {
        log.info("生成任务PDF报告: {}", taskId);

        try {
            // 构建请求头
            HttpHeaders headers = buildHeaders();

            // 构建请求实体
            HttpEntity<?> requestEntity = new HttpEntity<>(headers);

            // 构建完整URL
            String url = apiConfig.getBaseUrl() + apiConfig.getTaskPdfPath() + "/" + taskId;
            log.info("调用外部API: {}", url);


            // 发送请求
            ResponseEntity<ExternalApiResponse<TaskPDFResponse>> responseEntity = restTemplate.exchange(
                    url,
                    HttpMethod.POST,
                    requestEntity,
                    new ParameterizedTypeReference<ExternalApiResponse<TaskPDFResponse>>() {}
            );

            // 处理响应
            ExternalApiResponse<TaskPDFResponse> apiResponse = responseEntity.getBody();
            log.info("外部API响应: {}", apiResponse);

            if (apiResponse == null) {
                throw new BusinessException("外部API响应为空");
            }

            if (!apiResponse.isSuccess()) {
                throw new BusinessException("外部API调用失败: " + apiResponse.getMessage());
            }

            // 处理下载URL，确保它是完整的URL
            TaskPDFResponse pdfResponse = apiResponse.getData();
            if (pdfResponse != null && pdfResponse.getDownloadUrl() != null) {
                // 如果下载URL是相对路径，则添加基础URL
                if (pdfResponse.getDownloadUrl().startsWith("/")) {
                    String fullDownloadUrl = apiConfig.getBaseUrl() + pdfResponse.getDownloadUrl();
                    pdfResponse.setDownloadUrl(fullDownloadUrl);
                    log.info("完整下载URL: {}", fullDownloadUrl);
                }
            }

            return pdfResponse;
        } catch (RestClientException e) {
            log.error("调用外部API异常", e);
            throw new BusinessException("调用外部API异常: " + e.getMessage());
        } catch (Exception e) {
            log.error("生成任务PDF报告异常", e);
            throw new BusinessException("生成任务PDF报告异常: " + e.getMessage());
        }
    }

    /**
     * 生成任务网页报告
     * @param taskId 任务ID
     * @param regenerate 是否重新生成
     * @return 网页生成响应
     */
    @Override
    public TaskWebpageResponse generateTaskWebpage(String taskId, boolean regenerate) {
        log.info("生成任务网页报告: {}, regenerate: {}", taskId, regenerate);

        try {
            // 构建请求头
            HttpHeaders headers = buildHeaders();

            // 构建请求实体
            HttpEntity<?> requestEntity = new HttpEntity<>(headers);

            // 构建完整URL，添加regenerate参数
            String url = apiConfig.getBaseUrl() + apiConfig.getTaskWebpagePath() + "/" + taskId + "?regenerate=" + regenerate;
            log.info("调用外部API: {}", url);

            // 发送请求
            ResponseEntity<ExternalApiResponse<TaskWebpageResponse>> responseEntity = restTemplate.exchange(
                    url,
                    HttpMethod.GET, // 使用GET请求
                    requestEntity,
                    new ParameterizedTypeReference<ExternalApiResponse<TaskWebpageResponse>>() {}
            );

            // 处理响应
            ExternalApiResponse<TaskWebpageResponse> apiResponse = responseEntity.getBody();
            log.info("外部API响应: {}", apiResponse);

            if (apiResponse == null) {
                throw new BusinessException("外部API响应为空");
            }

            if (!apiResponse.isSuccess()) {
                throw new BusinessException("外部API调用失败: " + apiResponse.getMessage());
            }

            // 处理网页URL，确保它是完整的URL
            TaskWebpageResponse webpageResponse = apiResponse.getData();
            if (webpageResponse != null && webpageResponse.getWebpageUrl() != null) {
                // 如果网页URL是相对路径，则添加基础URL
                if (webpageResponse.getWebpageUrl().startsWith("/")) {
                    // 优先使用配置的网页基础URL，如果没有则使用API基础URL
                    String baseUrl = StringUtils.hasText(apiConfig.getWebpageBaseUrl())
                        ? apiConfig.getWebpageBaseUrl()
                        : apiConfig.getBaseUrl();

                    String fullWebpageUrl = baseUrl + webpageResponse.getWebpageUrl();
                    webpageResponse.setWebpageUrl(fullWebpageUrl);
                    log.info("完整网页URL: {}", fullWebpageUrl);
                }
            }

            return webpageResponse;
        } catch (RestClientException e) {
            log.error("调用外部API异常", e);
            throw new BusinessException("调用外部API异常: " + e.getMessage());
        } catch (Exception e) {
            log.error("生成任务网页报告异常", e);
            throw new BusinessException("生成任务网页报告异常: " + e.getMessage());
        }
    }
}
